package com.jaydenxiao.common.manager;

import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import com.jaydenxiao.common.baseapp.BaseApplication;
import com.jaydenxiao.common.basebean.BaseRespose;
import com.jaydenxiao.common.commonutils.JsonUtils;
import com.jaydenxiao.common.commonutils.NetWorkUtils;
import com.jaydenxiao.common.token.TokenUtil;
import com.jaydenxiao.common.url.BaseConstant;

import java.io.File;
import java.net.URL;
import java.util.concurrent.TimeUnit;

import me.jessyan.autosize.utils.LogUtils;
import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;
import okio.BufferedSource;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * ClassName: RetrofitManager<p>
 * Fuction: Retrofit请求管理类<p>
 * CreateDate:2016/2/13 20:34<p>
 * UpdateUser:<p>
 * UpdateDate:<p>
 */
public enum RetrofitManager {

    INSTANCE;
    //设缓存有效期为两天
    private static final long CACHE_STALE_SEC = 60 * 60 * 24 * 2;
    //查询缓存的Cache-Control设置，为if-only-cache时只查询缓存而不会请求服务器，max-stale可以配合设置缓存失效时间
    private static final String CACHE_CONTROL_CACHE = "only-if-cached, max-stale=" + CACHE_STALE_SEC;
    //查询网络的Cache-Control设置，头部Cache-Control设为maxd-age=0时则不会使用缓存而请求服务器
    private static final String CACHE_CONTROL_NETWORK = "max-age=0";
    private static final int TIME_OUT = 20;  //超时时间
    private static volatile OkHttpClient mOkHttpClient;
    private static Retrofit mRetrofit;


    //有传token的请求进行拦截跳到登陆BaseConstant.BASEURL
    public Retrofit net() {
        if (mRetrofit == null) {
            initOkHttpClient();
            Gson gson = new GsonBuilder()
                    .setLenient()
                    .create();
            mRetrofit = new Retrofit.Builder().baseUrl(HttpUrl.get(BaseConstant.BASEURL)).client(mOkHttpClient)
                    .addConverterFactory(ExGsonConverterFactory.create(gson))
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .build();
        }
        return mRetrofit;
    }

    public static void setClearRetrofit() {
        if (mRetrofit != null) {
            mRetrofit = null;
        }
    }

    // 配置OkHttpClient
    public void initOkHttpClient() {
        if (mOkHttpClient == null) {
            synchronized (RetrofitManager.class) {
                //有公共参数进行加密
                if (mOkHttpClient == null) {
                    //开启Log
                    HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor();
                    logInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
                    //   LogUtils.e("初始化mOkHttpClient");
                    // 因为BaseUrl不同所以这里Retrofit不为静态，但是OkHttpClient配置是一样的,静态创建一次即可
                    // 指定缓存路径,缓存大小100Mb
                    Cache cache = new Cache(new File(BaseApplication.getAppContext().getCacheDir(), "HttpCache"),
                            1024 * 1024 * 100);
                    OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
                    okHttpBuilder
                            .cache(cache)
                            .addNetworkInterceptor(mRewriteCacheControlInterceptor)//网络读写缓存拦截器
                           // .addInterceptor(new NoNetInterceptor())    //将无网络拦截器当做应用拦截器添加
                          //  .addNetworkInterceptor(new NetInterceptor()) //将有网络拦截器当做网络拦截器添加
                            .addInterceptor(logInterceptor)   //log打印
                            .retryOnConnectionFailure(true)//尝试进行重新连接
                            .connectTimeout(TIME_OUT, TimeUnit.SECONDS)// 设置连接时间
                            .readTimeout(TIME_OUT, TimeUnit.SECONDS)//设置读写时间
                            .writeTimeout(TIME_OUT, TimeUnit.SECONDS);//设置请求超时;

                    mOkHttpClient = okHttpBuilder.build();

                }
            }
        }
    }


    /**
     * 云端响应头拦截器，用来配置缓存策略
     * Dangerous interceptor that rewrites the server's cache-control header.
     */
    private Interceptor mRewriteCacheControlInterceptor = chain -> {
        Request request = chain.request();
        String cacheControl = request.cacheControl().toString();
        //添加头部数据
        request = request.newBuilder()
                    .cacheControl(TextUtils.isEmpty(cacheControl)?CacheControl.FORCE_NETWORK:CacheControl.FORCE_CACHE)
                    .header("Accept","application/json")
                    .header("Authorization", TokenUtil.getAuthorization())
                    .build();

        Response originalResponse = chain.proceed(request);
        Response.Builder  newResponse=originalResponse.newBuilder();
        if(originalResponse.code()==401){
            //构建一个response参数
            BaseRespose<String> baseRespose=new BaseRespose<>();
            baseRespose.setCode(201);
            baseRespose.setMsg("token失效，重新登录");
            baseRespose.setMeta("");
           String resposeJson= JsonUtils.toJson(baseRespose);
            ResponseBody newsResponseBody = ResponseBody.create(MediaType.parse("application/json; charset=UTF-8"), resposeJson);
            newResponse.body(newsResponseBody);
            newResponse.code(201);
            Log.e("jc--->",baseRespose.toString());
        }


        if(originalResponse.code()==404){
            Log.e("tis--->",originalResponse.code()+"");
        }
        if (NetWorkUtils.isNetConnected(BaseApplication.getAppContext())) {
            //有网的时候读接口上的@Headers里的配置，你可以在这里进行统一的设置
            return  newResponse
                   // .removeHeader("Pragma")
                    .header("Connection", "close")
                    .header("Connection","close")
                    .header("Accept","application/json")
                    .header("Authorization", TokenUtil.getAuthorization())
                   // .header("Cache-Control", "public, max-age=" + 90)
                    .build();
        } else {
            return newResponse
                    //.header("Cache-Control", "public, only-if-cached, max-stale=3600")
                    .header("Accept","application/json")
                    .header("Connection","close")
                    .header("Authorization", TokenUtil.getAuthorization())
                   // .removeHeader("Pragma")
                    .build();
        }
    };

    /**
     * 根据网络状况获取缓存的策略
     **/
    @NonNull
    public String getCacheControl() {
        return NetWorkUtils.isNetConnected(BaseApplication.getAppContext()) ? CACHE_CONTROL_NETWORK : CACHE_CONTROL_CACHE;
    }

}
